/*
 * jQuery-Seat-Charts v1.1.0
 * http://www.sucaijiayuan.com
*/


(function ($) {
	const CIRCLETABLE = '2';
	const TIAOXINGTABLE = '4';
	const JUXINGTABLE = '1';
	const SEATS = {
		// f: { 
		// 	price   : 100,
		// 	classes : 'first-class', //your custom CSS class
		// 	category: '主席台'
		// },
		// e: {
		// 	price   : 40,
		// 	classes : 'economy-class', //your custom CSS class
		// 	category: '座位'
		// },
		// g: {
		// 	price   : 400,
		// 	classes : 'vip-class', //your custom CSS class
		// 	category: 'vip'
		// }	
	};

	$.extend({
		change_map: function (_this, item, id, type, changeHrm) { // 改变map
			let strtype = item.map || 'e';
			let bgcolor = item.backgroundColor;
			var t_map = _this && _this.data('map');
			if (typeof (id) == undefined) {
				return;
			}
			var row = parseInt(id.split("_")[0], 10) - 1;
			var col = parseInt(id.split("_")[1], 10) - 1;
			if (t_map && typeof (t_map[0]) == 'string') {
				for (var item in t_map) {
					var str = t_map[item];
					if (item == row) {
						t_map[item] = str.substring(0, col) + strtype + str.substring(col + 1);
					}
				}
				_this.data('map', t_map);
			}
			if (t_map && t_map[0] instanceof Array) {
				t_map.map((res, index) => {
					if (index == row) {
						if (type && type == 'arrange') { //安排座位
							t_map[row][col] = { ...res[col], showname: item.name, hrmid: item.id,};
							changeHrm && changeHrm(item.id, '', item.seatId, item.seatLabel, item.tableNum)
						} else {
							t_map[row][col] = { ...res[col], map: strtype, bgcolor: bgcolor };
						}
					}
				});
				_this.data('map', t_map);
			}

		},
		close_span_pre: function (changeHrm, getOutsideHrmModal, seat_Label, node) {
			let style = node ? {color: $(node).css('color'), opacity: 0.7} : {}
			return (
				$('<span class="close icon-coms-Clear"></span>')
					.css(style)
					.on('click', function (e) {
						var hrmid = $(this).parent().attr('hrmid');
						var id = $(this).parent().attr('id');
						var parentDom = '#' + $(this).closest('.seatCharts-container').attr('id');
						const clearHrm = () => {
							if (hrmid && hrmid != '') {
								typeof (changeHrm) == 'function' && changeHrm('', hrmid);
								$(this).parent().text(
									$(this).parent().attr('hrmid', '').attr('label')
									// $._label_pre( $(this).parent().attr('hrmid', '').attr('id'), seat_Label )
								);
								$.change_map($(parentDom), { id: '', name: '' }, id, 'arrange');
								if($(`.color-area.oneself[hrmid=${hrmid}]`).length > 0) { // 移除本人图标
									$(`.color-area.oneself[hrmid=${hrmid}]`).remove();
								}
							}
						}
						if (hrmid == 'outsideHrm') {
							window.clearHrm_pre = () => clearHrm();
							getOutsideHrmModal();
						} else {
							clearHrm();
						}
					
						return false;
					})
			);
		},
		batch_Seating_map: function (map_arr, id, hrm) {
			var row = parseInt(id.split("_")[0], 10) - 1;
			var col = parseInt(id.split("_")[1], 10) - 1;
			if (map_arr && map_arr instanceof Array) {
				map_arr.map((item, index) => {
					if (index == row) {
						map_arr[row][col] = { ...item[col], showname: hrm.name, hrmid: hrm.id, memberType: hrm.memberType || '' };
					}
				})
			}
		},
		batch_Seating: function (isClickArrangeSeat, hrmObj, changeHrm, clear, hrmroomid) { // 批量排座
			var seats = $('.seatCharts-container').last().find('.seatCharts-seat');
			if (clear) { // 清空人员数据和排座数据
				hrmObj && hrmObj.map(res => {
					if (isClickArrangeSeat) {
					} else {
						res.roomid == hrmroomid && changeHrm('', res.id, '', '', '');
					}
				})
				seats && seats.map(res => {
					var temp = seats[res];
					if ( $(temp).attr('hrmid') == 'outsideHrm') {
						// 外部人员不清空 
					} else if (isClickArrangeSeat && $(temp).attr('hrmid') != '') { // 已排座人员不清空 
					} else {
						$.batch_Seating_map($(temp).closest('.seatCharts-container').data('map'), $(temp).attr('id'), { name: '', id: '' });
						$(temp).attr('hrmid', '').text($(temp).attr('label'));
					} 
				})
			} else {
				var hrm_obj = hrmObj;
				var hrmcounts = 0;
				seats && seats.map(res => {
					var temp = seats[res];
					if ( isClickArrangeSeat && $(temp).attr('hrmid') != '' ) { // 跳过已经排好座位的已排座人员
					} else if ( $(temp).attr('hrmid') == 'outsideHrm' ) { // 跳过已经排好座位的外部人员
					} else {
						if (hrm_obj[hrmcounts]) { // 有会议室的人员不需要排座
							for (var i = 0; i < hrm_obj.length; i++) {
								if (hrm_obj[i].roomid == '') {
									$.batch_Seating_map($(temp).closest('.seatCharts-container').data('map'), $(temp).attr('id'), hrm_obj[i]);
									changeHrm(hrm_obj[i].id, '', $(temp).attr('id'), $(temp).attr('label'), $(temp).attr('tablenum'));
									$(temp).attr('hrmid', hrm_obj[i].id).text(hrm_obj[i].name);
									hrm_obj[i] = { ...hrm_obj[i], roomid: hrmroomid };
									break;
								}
							}
							hrmcounts ++;
						} else {
							$.batch_Seating_map($(temp).closest('.seatCharts-container').data('map'), $(temp).attr('id'), { name: '', id: '' });
							$(temp).attr('hrmid', '').text($(temp).attr('label'));
						}
					}
				})
			}
			var onself_hrmid = window.meetingSeatOneselfHrmid;
			if($(`.color-area.oneself[hrmid=${onself_hrmid}]`).length > 0) { // 移除本人图标
				$(`.color-area.oneself[hrmid=${onself_hrmid}]`).remove();
			}
		},
		_label_pre: function (label, string) {
			var res = label;
			if (label && typeof (label) == 'string') {
				var L = label.split('_');
				if (L.length == 2 && (string[0] == '排' || string[0] == '排')) {
					res = L[0] + string[0] + L[1] + string[1];
				}
			}
			return res;
		},
		dblclick_defined_pre: function (_this) { // 自定义座位编号
			if (_this.node().attr('hrmid')) return;
			if (_this.node().hasClass('available')) {
				var oldlabel = _this.node().text();
				var inputdom = $('<input id="dblclick_input" type="text"/>')
					.addClass('dblclick_input')
					.val(oldlabel)
					.on('click', function () { return false; })
					.on('dblclick', function () { return false; })
					.on('blur', function () {
						_this.node().children('#dblclick_input').remove();
						if (this.value === '') {
							_this.node().text(oldlabel);
						} else {
							let roomid = _this.node().closest('.seatCharts-container').attr('roomId');
							var item = { hrmid: 'outsideHrm', memberType: "3", showname: this.value, roomid: roomid };
							$.change_map_seatLabel_pre(_this.node().closest('.seatCharts-container'), item, _this.node().attr('id'))
						
							_this.node().text(this.value);
						}
					});
				var $mask = $('<div id="mask_input"></div>').on('mousedown', function () {
					$('#mask_input').remove();
				});
				_this.node().text('').append(inputdom);
				$('#seat-map').after($mask);
				inputdom.focus();
			}
		},
		change_map_seatLabel_pre: function (_this, item, id) {
			var t_map = _this.data('map');
			var row = 0;
			var col = 0;
			if (id) {
				row = parseInt(id.split("_")[0], 10) - 1;
				col = parseInt(id.split("_")[1], 10) - 1;
			}
			if (t_map[0] instanceof Array) {
				t_map.map((res, index) => {
					if (index == row) {
						t_map[row][col] = { ...res[col],...item, hrmid: item.hrmid, memberType: '3', showname: item.showname };
					}
				});
				// _this.data('map', t_map);
			}
		},

	});


	$.fn.seatCharts_pre = function (setup) {
		//if there's seatCharts object associated with the current element, return it
		if (this.data('seatCharts')) {
			if (setup && setup.needFresh) {
				$(this).html("");
				this.removeData('seatCharts');
			} else {
				return this.data('seatCharts');
			}
		}

		function celarHrm(operationType, _this) {

		}
		var opcityBlock_move = false;
		var floatingLayer = $('<div class="floatingLayer"></div>').css({
			position: 'absolute', height: '32px', 'line-height': '32px', width: '64px',
			backgroundColor: '#000', color: '#fff', opacity: '0.2', 'text-align': 'center', 'border-radius': '5px'
		});
		var temp_cloumn = 0;
		var temp_row = 0;
		var temp_count = 0;
		var has_onself = false;
		var oneself_dom = '';
		var onself_hrmid = '';
		var fn = this,
			model = setup.model, // 布局类型
			tableNum = setup.tableNum, // 桌号
			right_Menu = setup.rightMenu, // 右键菜单选项
			operationType = setup.operationType, // 操作类型
			seatType = setup.seatType, // 座位布局类型
			countDirection = setup.countDirection, // 计数方向
			seatLabelStyle = setup.seatLabelStyle, // 座位编号类型
			changeHrm = setup.changeHrm, // 删除已添加人员
			hrmNameMap = setup.hrmNameMap, // 人员json
			getFirstHrmName = setup.getFirstHrmName,
			store_selectedSeats = setup.selectedSeats,
			store_setState = setup.setState,
			store_getState = setup.getState,
			getModal = setup.getModal,
			getOutsideHrmModal = setup.getOutsideHrmModal,
			oneself_seat = setup.oneselfSeat,
			seat_Label = setup.seatLabel,
			seats = {},
			seatIds = [],
			legend,
			settings = {
				hiddenSign: 'w',
				animate: false, //requires jQuery UI
				naming: {
					top: true,
					left: true,
					getId: function (character, row, column) {
						return row + '_' + column;
					},
					getLabel: function (character, row, column) {
						if (seatType == 'square') {
							if (seatLabelStyle == '3') {
								var list = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
								return list[(row % 26 - 1)] + column;
							} else if (seatLabelStyle == '2') {
								return row + '-' + column;
							} else {
								return ++temp_count;
							}
						} else if (seatType == 'circle') {
							var t = Math.ceil(setup.circleSeats / 4) + 2;
							var col = Math.ceil((setup.circleSeats - 2 * (t - 2)) / 2) + 2;
							return ++temp_count;

						} else {
							return ++temp_count;
						}
					}
				},
				legend: {
					node: null,
					items: []
				},
				seatType: setup.seatType,
				click: function () {
					var _this = this;
					if (operationType == 'preview') {
						clearTimeout(window.timer_);
						window.timer_ = setTimeout(() => {
							var oldid = _this.node().attr('hrmid');
							var currentid = _this.settings.id;
	
							var s_time, e_time, cleartimeout;
							store_setState({
								floatingLayer_before_seatId: currentid,
								before_table_number: tableNum,
								before_seat_label: _this.node().attr('label'),
							});
							function mouse_down(e) {
								s_time = new Date().getTime();
								cleartimeout = setTimeout(function () {
									if (oldid) {
										var Left = $(e.target).offset().left;
										var Top = $(e.target).offset().top;
										var L = $('#seat-map').offset().left;
										var T = $('#seat-map').offset().top;
										var scrollLeft = $('#seat-map').scrollLeft();
										var scrollTop = $('#seat-map').scrollTop();
										floatingLayer.text(_this.node().text()).css({ left: Left - L + scrollLeft, top: Top - T + scrollTop });
										$('#seat-map').append(floatingLayer);
										store_setState({ floatingLayer_before_dom: fn, floatingLayer_before_seatId: currentid, floatingLayer_before_hrmId: oldid });
										opcityBlock_move = true;
									}
								}, 250);
							}
							function mouse_up() {
								e_time = new Date().getTime();
								if (e_time - s_time < 250) {
									clearTimeout(cleartimeout);
								}
							}
	
							$.each($(fn).find('.close'), function (index, res) {
								$(res).remove();
							})
							if (oldid && _this.node().find('.close').length == 0) { // 选中并显示关闭图标
								_this.node().append($.close_span_pre(changeHrm, getOutsideHrmModal, seat_Label, _this.node()))
							}
							if (_this.node().children('.opcityBlock').length == 0) {// 遮罩层
								$.each($(fn).find('.opcityBlock'), function (index, res) {
									$(res).remove();
								})
								var opacity_block = $('<div class="opcityBlock"></div>') // 浮层
									.on('mousedown', mouse_down)
									.on('mouseup', mouse_up);
							
								_this.node().append(opacity_block);
							} else {
								_this.node().find('.opcityBlock, .close').remove();
							}
	
							store_selectedSeats(currentid, oldid, fn); // 选位置
	
							if (false && getFirstHrmName().id && false) {
								var oldid = this.node().attr('hrmid');
								var newid = getFirstHrmName().id;
								var $close = $.close_span_pre(changeHrm);
								this.node().text(getFirstHrmName().name).append($close);
								this.node().attr('hrmid', newid)
								changeHrm(newid, oldid);
							}
						}, 250);
					} else if (operationType == 'only_pre') {
						if (_this.node().attr('label') == _this.node().text()) {
							_this.node().text(_this.node().attr('showname'));
						} else {
							_this.node().text(_this.node().attr('label'));
						}
					}
					return 'available';
				},
				focus: function () {
					$(this.node()).attr('title', $(this.node()).text())
					return 'available';
				},
				blur: function () {
					if (operationType == 'only_pre') {
						var _this = this;
						setTimeout(function (_this) {
							$(this.node()).text($(this.node()).attr('showname'))
						}.bind(this), 300)
					}
					return this.status();
				},
				contextmenu: function () {
					var _this = this;
					if (operationType == 'set') {
						_this.node().append('<div id="opcityBlock" class="opcityBlock"></div>'); // 遮罩层
						function removeDom() {
							$('#mouseline').remove();
							$('#rightmenu').remove();
							$('#mask').remove();
						}

						$('#rightmenu').remove();
						if (!(this.status() == 'hidden')) {
							var positionX = document.getElementById('seat-map').getBoundingClientRect().x;
							var positionY = document.getElementById('seat-map').getBoundingClientRect().y;
							var L = $(fn).offset().left, T = $(fn).offset().top;
							var $mask = $('<div id="mask"></div>').on('click', function () {
								$(this).remove();
								removeDom();
								_this.node().find('#opcityBlock').remove();
							});
							var $rightmenu = $('<div id="rightmenu"></div>')
								.addClass('right-menu');
							$rightmenu.css({
								'left': this.node().offset().left - L + 40 + 'px',
								'top': this.node().offset().top - T + 20 + 'px'
							});
							if (this.node().offset().left > 790) {
								$rightmenu.css({
									'left': this.node().offset().left - 40 - L + 'px',
								});
							}
							if (this.node().offset().top > 550) {
								$rightmenu.css({
									'top': this.node().offset().top - T - right_Menu.length * 30 + 'px'
								});
							}
							$.each(right_Menu, function (index, item) {
								var spanstr = $('<div></div>')
									.addClass('menu-list')
									.text(item.value)
									.on('click', function (e) {
										var value = item.map;
										var id = _this.settings.id;
										var text = $(this).text();
										if (item.unavailable) {
											_this.node().removeClass('available').addClass('unavailable');
										} else {
											_this.node().removeClass('unavailable').addClass('available');
										}
										if (model == TIAOXINGTABLE && item.key == 'passageway') {
											_this.node().css({ 'background-color': '#E4E9F0', 'color': '#E4E9F0' });
										} else {
											_this.node().css('background-color', item.backgroundColor);
										}
										_this.node().find('#opcityBlock').remove();
										$.change_map(fn, item, id);
										removeDom();
									});;
								$rightmenu.append(spanstr)
							})
							$(fn).append($rightmenu);
							$('#seat-map').after($mask);
						}
					}
					window.event.returnValue = false;
					return _this.status();
				},
				dblclick: function () { // 清空排座人员
					if (operationType == 'preview') {
						clearTimeout(window.timer_); // 清除单击事件
						var _this = this;
						$.dblclick_defined_pre(_this);
					}
					return 'available';
				},
				seats: {}

			};
		//seat will be basically a seat object which we'll when generating the map
		var seat = (function (seatCharts, seatChartsSettings) {

			return function (setup) {
				var fn = this;
				fn.tableNum = tableNum;
				fn.settings = $.extend({
					status: 'available', //available, unavailable, selected
					style: 'available',
					//make sure there's an empty hash if user doesn't pass anything
					data: seatChartsSettings.seats[setup.character] || {},
					hiddenSign: seatChartsSettings.hiddenSign || '',
					//anything goes here?
					label: $._label_pre((setup.row + 1) + '_' + (setup.column + 1), seat_Label)// 座位号 tableNum+'-'+(setup.row+1)+'-'+(setup.column+1)
				}, setup);

				fn.settings.$node = $('<div></div>')
				if (fn.settings.hiddenSign != '' && fn.settings.hiddenSign == fn.settings.character) {
					fn.settings.status = 'hidden';
					fn.settings.style = 'hidden';
				}

				var string = fn.settings.showname == '' ? fn.settings.label : fn.settings.showname;

				fn.settings.$node
					.attr({
						id: fn.settings.id,
						role: 'checkbox',
						label: fn.settings.label,
						'aria-checked': false,
						focusable: true,
						tabIndex: -1,//manual focus
						tablenum: tableNum,
						showname: fn.settings.showname == '' ? fn.settings.label : fn.settings.showname
					})
					// .html()
					.html(string)
					.addClass(['seatCharts-seat', 'seatCharts-cell', 'seat-item', fn.settings.style].concat(
						//let's merge custom user defined classes with standard JSC ones
						fn.settings.classes,
					).join(' '))
					// .css({'background-color': typeof seatChartsSettings.seatType[fn.settings.character] == "undefined" ?  ////5-22
					// 													'' : seatChartsSettings.seatType[fn.settings.character].bgcolor});
					.css({
						'background-color': typeof fn.settings.bgcolor != undefined ? (fn.settings.bgcolor)
							: (seatChartsSettings.seatType[fn.settings.character] ? seatChartsSettings.seatType[fn.settings.character].bgcolor : ''),
						'color': typeof fn.settings.color != undefined ? fn.settings.color : 'red',
					}); //
				if (String(fn.settings.hrmid) == String(oneself_seat)) { // 本人
					has_onself = true;
					oneself_dom = fn.settings.$node.attr('id');
					onself_hrmid = fn.settings.hrmid;
					window.meetingSeatOneselfHrmid = onself_hrmid;
				}

				//basically a wrapper function
				fn.data = function () {
					return fn.settings.data;
				};

				fn.char = function () {
					return fn.settings.character;
				};

				fn.node = function () {
					return fn.settings.$node;
				};

				/*
					* Can either set or return status depending on arguments.
					*
					* If there's no argument, it will return the current style.
					*
					* If you pass an argument, it will update seat's style
					*/
				fn.style = function () {

					return arguments.length == 1 ?
						(function (newStyle) {
							var oldStyle = fn.settings.style;

							//if nothing changes, do nothing
							if (newStyle == oldStyle) {
								return;
							}

							//focused is a special style which is not associated with status
							fn.settings.status = newStyle != 'focused' ? newStyle : fn.settings.status;
							fn.settings.$node
								.attr('aria-checked', newStyle == 'selected');

							//if user wants to animate status changes, let him do this
							seatChartsSettings.animate ?
								fn.settings.$node.switchClass(oldStyle, newStyle, 200) :
								fn.settings.$node.removeClass(oldStyle).addClass(newStyle).removeClass('');

							return fn.settings.style = newStyle;
						})(arguments[0]) : fn.settings.style;
				};

				//either set or retrieve
				fn.status = function () {

					return fn.settings.status = arguments.length == 1 ?
						fn.style(arguments[0]) : fn.settings.status;
				};

				//using immediate function to convienietly get shortcut variables
				(function (seatSettings, character, seat) {

					// //attach event handlers
					$.each(['click', 'focus', 'blur', 'contextmenu', 'dblclick'], function (index, callback) {
						fn[callback] = function () {
							if (callback == 'focus') {
								//if there's already a focused element, we have to remove focus from it first
								if (seatCharts.attr('aria-activedescendant') !== undefined) {
									seats[seatCharts.attr('aria-activedescendant')].blur();
								}
								seatCharts.attr('aria-activedescendant', seat.settings.id);
								seat.node().focus();
							}

							return fn.style(typeof seatSettings[character][callback] === 'function' ?
								seatSettings[character][callback].apply(seat) : seatChartsSettings[callback].apply(seat));
						};
					});

					//the below will become seatSettings, character, seat thanks to the immediate function		
				})(seatChartsSettings.seats, fn.settings.character, fn);

				fn.node() // 为每个节点绑定事件
					// the first three mouse events are simple
					.on('click', fn.click)
					.on('mouseenter', fn.focus)
					.on('mouseleave', fn.blur)
					.on('contextmenu', fn.contextmenu)
					.on('dblclick', fn.dblclick)
					//keydown requires quite a lot of logic, because we have to know where to move the focus
					.on('keydown', (function (seat, $seat) {

						return function (e) {

							var $newSeat;

							//everything depends on the pressed key
							switch (e.which) {
								//spacebar will just trigger the same event mouse click does
								case 32:
									e.preventDefault();
									seat.click();
									break;
								//UP & DOWN
								case 40:
								case 38:
									e.preventDefault();

									/*
										* This is a recursive, immediate function which searches for the first "focusable" row.
										* 
										* We're using immediate function because we want a convenient access to some DOM elements
										* We're using recursion because sometimes we may hit an empty space rather than a seat.
										*
										*/
									$newSeat = (function findAvailable($rows, $seats, $currentRow) {
										var $newRow;

										//let's determine which row should we move to

										if (!$rows.index($currentRow) && e.which == 38) {
											//if this is the first row and user has pressed up arrow, move to the last row
											$newRow = $rows.last();
										} else if ($rows.index($currentRow) == $rows.length - 1 && e.which == 40) {
											//if this is the last row and user has pressed down arrow, move to the first row
											$newRow = $rows.first();
										} else {
											//using eq to get an element at the desired index position
											$newRow = $rows.eq(
												//if up arrow, then decrement the index, if down increment it
												$rows.index($currentRow) + (e.which == 38 ? (-1) : (+1))
											);
										}

										//now that we know the row, let's get the seat using the current column position
										$newSeat = $newRow.find('.seatCharts-seat,.seatCharts-space').eq($seats.index($seat));

										//if the seat we found is a space, keep looking further
										return $newSeat.hasClass('seatCharts-space') ?
											findAvailable($rows, $seats, $newRow) : $newSeat;

									})($seat
										//get a reference to the parent container and then select all rows but the header
										// .parents('.seatCharts-container')
										.find('.seatCharts-row:not(.seatCharts-header)'),
										$seat
											//get a reference to the parent row and then find all seat cells (both seats & spaces)
											.parents('.seatCharts-row:first')
											.find('.seatCharts-seat,.seatCharts-space'),
										//get a reference to the current row
										$seat.parents('.seatCharts-row:not(.seatCharts-header)')
									);

									//we couldn't determine the new seat, so we better give up
									if (!$newSeat.length) {
										return;
									}

									//remove focus from the old seat and put it on the new one
									seat.blur();
									seats[$newSeat.attr('id')].focus();
									$newSeat.focus();

									//update our "aria" reference with the new seat id
									seatCharts.attr('aria-activedescendant', $newSeat.attr('id'));

									break;
								//LEFT & RIGHT
								case 37:
								case 39:
									e.preventDefault();
									/*
										* The logic here is slightly different from the one for up/down arrows.
										* User will be able to browse the whole map using just left/right arrow, because
										* it will move to the next row when we reach the right/left-most seat.
										*/
									$newSeat = (function ($seats) {

										if (!$seats.index($seat) && e.which == 37) {
											//user has pressed left arrow and we're currently on the left-most seat
											return $seats.last();
										} else if ($seats.index($seat) == $seats.length - 1 && e.which == 39) {
											//user has pressed right arrow and we're currently on the right-most seat
											return $seats.first();
										} else {
											//simply move one seat left or right depending on the key
											return $seats.eq($seats.index($seat) + (e.which == 37 ? (-1) : (+1)));
										}

									})($seat
										.parents('.seatCharts-container:first')
										.find('.seatCharts-seat:not(.seatCharts-space)'));

									if (!$newSeat.length) {
										return;
									}

									//handle focus
									seat.blur();
									seats[$newSeat.attr('id')].focus();
									$newSeat.focus();

									//update our "aria" reference with the new seat id
									seatCharts.attr('aria-activedescendant', $newSeat.attr('id'));
									break;
								default:
									break;

							}
						};

					})(fn, fn.node()));
				//.appendTo(seatCharts.find('.' + row));
			}
		})(fn, settings);

		//true -> deep copy!
		$.extend(true, settings, setup);

		//Generate default row ids unless user passed his own
		settings.naming.rows = settings.naming.rows || (function (length) {
			var rows = [];
			for (var i = 1; i <= length; i++) {
				rows.push(i);
			}
			return rows;
		})(settings.map.length);

		//Generate default column ids unless user passed his own
		settings.naming.columns = settings.naming.columns || (function (length) {
			var columns = [];
			for (var i = 1; i <= length; i++) {
				columns.push(i);
			}
			return columns;
		})(typeof (settings.map[0]) == 'string' ? settings.map[0].split('').length : settings.map[0] && settings.map[0].length); /////5-22

		//top 
		if (settings.naming.top) {
			var $headerRow = $('<div></div>')
				.addClass('seatCharts-row seatCharts-header');

			if (settings.naming.left) {
				$headerRow.append($('<div></div>').addClass('seatCharts-cell'));
			}

			$.each(settings.naming.columns, function (index, value) {
				$headerRow.append(
					$('<div></div>')
						.addClass('seatCharts-cell')
						.text(value)
				);
			});
		}

		fn.append($headerRow);

		//do this for each map row
		$.each(settings.map, function (row, characters) {
			temp_row = row + 1;
			var col = 1;
			var $row = $('<div row=' + (row + 1) + '></div>').addClass('seatCharts-row');

			if (settings.naming.left) {
				$row.append(
					$('<div class="seat-item" row=' + (row + 1) + ' col=' + (col) + ' id=' + (row + 1) + '_' + (col) + '></div>')
						.addClass('seatCharts-cell seatCharts-space')
						.text(settings.naming.rows[row])
				);
			}

			temp_cloumn = 0;

			if (characters instanceof Array) {
				$.each(characters, function (column, characterParams) { /////5-22
					temp_cloumn++;
					var matches = characterParams,
						character = characterParams.map,
						overrideLabel = hrmNameMap && typeof(hrmNameMap[characterParams.hrmid])==='undefined' ? characterParams.showname 
							: hrmNameMap[characterParams.hrmid];
						// overrideLabel = characterParams.showname;
					$row.append(character != '_' ?
						(function (naming) {
							settings.seats[character] = character in settings.seats ? settings.seats[character] : {};
							var id = naming.getId(character, naming.rows[row], naming.columns[column]);
							seats[id] = new seat({
								id: id,
								// label     : naming.getLabel(character, naming.rows[row], naming.columns[column]),
								label: characterParams.isEditLabel ? characterParams.seatLabel_def : $._label_pre(characterParams.seatLabel, seat_Label), // (characterParams.isEditLabel ? characterParams.seatLabel_def : $._label(characterParams.seatLabel, seat_Label)
								showname: overrideLabel ? overrideLabel : '',
								row: row,
								column: column,
								character: character,
								bgcolor: character == '_' ? '' : characterParams.bgcolor,  //// 5-22
								color: characterParams.color,
								hrmid: characterParams.hrmid ? characterParams.hrmid : '',
							});
							seats[id].node().attr('hrmid', characterParams.hrmid ? characterParams.hrmid : '');
							seatIds.push(id);
							return seats[id].node();
						})(settings.naming) :
						$('<div class="seat-item"  row=' + (row + 1) + ' col=' + (col) + ' id=' + (row + 1) + '_' + (col) + '></div>').addClass('seatCharts-cell seatCharts-space')
					);

					col++;

				});
			} else {
				$.each(characters.match(/[a-z_]{1}(\[[0-9a-z_]{0,}(,[0-9a-z_ ]+)?\])?/gi), function (column, characterParams) { /////5-22
					temp_cloumn++;
					var matches = characterParams.match(/([a-z_]{1})(\[([0-9a-z_ ,]+)\])?/i),
						//no matter if user specifies [] params, the character should be in the second element
						character = matches[1],
						//check if user has passed some additional params to override id or label
						params = typeof matches[3] !== 'undefined' ? matches[3].split(',') : [],
						//id param should be first
						overrideId = params.length ? params[0] : null,

						//label param should be second
						overrideLabel = params.length === 2 ? params[1] : null;
					$row.append(character != '_' ?
						//if the character is not an underscore (empty space)
						(function (naming) {
							//so users don't have to specify empty objects
							settings.seats[character] = character in settings.seats ? settings.seats[character] : {};

							var id = overrideId ? overrideId : naming.getId(character, naming.rows[row], naming.columns[column]);
							seats[id] = new seat({
								id: id,
								// label     : '' ,  
								label: overrideLabel ?
									overrideLabel : naming.getLabel(character, naming.rows[row], naming.columns[column]),
								row: row,
								column: column,
								character: character
							});

							seatIds.push(id);
							return seats[id].node();
						})(settings.naming) :
						//this is just an empty space (_)
						$('<div class="seat-item" row=' + (row + 1) + ' col=' + (col) + ' id=' + (row + 1) + '_' + (col) + '></div>').addClass('seatCharts-cell seatCharts-space')
					);

					col++;

				});
			}
			if (has_onself) { // 确定本人位置
				
				var t_col = oneself_dom && oneself_dom.split('_')[1];
				var t_width = 0;
				if (model == TIAOXINGTABLE) {
					t_width = parseInt(t_col, 10) * 80 - 30;
				} else if (model == CIRCLETABLE) {
					t_width = parseInt(t_col, 10) * 60;
				} else {
					t_width = parseInt(t_col, 10) * 70 - 20;
				}
				var self_dom = $('<div class="color-area oneself"><i class="icon-coms-man"/></div>').attr('hrmid', onself_hrmid).css({ 'left': t_width + 'px' });
				$row.children(':last-child').before(self_dom);
			}
			has_onself = false;

			fn.append($row);

		});

		// 条形桌中间过道
		var fuceng = $('<div class="fuceng"></div>');
		model == TIAOXINGTABLE ? fn.append(fuceng) : '';

		//if there're any legend items to be rendered
		settings.legend.items.length ? (function (legend) {
			//either use user-defined container or create our own and insert it right after the seat chart div
			var $container = (legend.node || $('<div></div').insertAfter(fn))
				.addClass('seatCharts-legend');

			var $ul = $('<ul></ul>')
				.addClass('seatCharts-legendList')
				.appendTo($container);

			$.each(legend.items, function (index, item) {
				$ul.append(
					$('<li></li>')
						.addClass('seatCharts-legendItem')
						.append(
							$('<div></div>')
								//merge user defined classes with our standard ones
								.addClass(['seatCharts-seat', 'seatCharts-cell', item[1]].concat(
									settings.classes,
									typeof settings.seats[item[0]] == "undefined" ? [] : settings.seats[item[0]].classes).join(' ')
								)
						)
						.append(
							$('<span></span>')
								.addClass('seatCharts-legendDescription')
								.text(item[2])
						)
				);
			});

			return $container;
		})(settings.legend) : null;

		fn.attr({
			tabIndex: 0
		});

		//public methods of seatCharts
		operationType == 'set' && fn.dragging({ right_Menu, model });
		fn.data('map', setup.map)
		fn.data('seatCharts', {
			tableNum: tableNum,
			seats: seats,
			seatIds: seatIds,
			//set for one, set for many, get for one
			status: function () {
				var fn = this;
				return arguments.length == 1 ? fn.seats[arguments[0]].status() : (function (seatsIds, newStatus) {

					return typeof seatsIds == 'string' ? fn.seats[seatsIds].status(newStatus) : (function () {
						$.each(seatsIds, function (index, seatId) {
							fn.seats[seatId].status(newStatus);
						});
					})();
				})(arguments[0], arguments[1]);
			},
			each: function (callback) {
				var fn = this;

				for (var seatId in fn.seats) {
					if (false === callback.call(fn.seats[seatId], seatId)) {
						return seatId;//return last checked
					}
				}

				return true;
			},
			node: function () {
				var fn = this;
				//basically create a CSS query to get all seats by their DOM ids
				return $('#' + fn.seatIds.join(',#'));
			},

			find: function (query) {//D, a.available, unavailable
				var fn = this;

				var seatSet = fn.set();

				//user searches just for a particual character
				return query.length == 1 ? (function (character) {
					fn.each(function () {
						if (this.char() == character) {
							seatSet.push(this.settings.id, this);
						}
					});

					return seatSet;
				})(query) : (function () {
					//user runs a more sophisticated query, so let's see if there's a dot
					return query.indexOf('.') > -1 ? (function () {
						//there's a dot which separates character and the status
						var parts = query.split('.');

						fn.each(function (seatId) {
							if (this.char() == parts[0] && this.status() == parts[1]) {
								seatSet.push(this.settings.id, this);
							}
						});

						return seatSet;
					})() : (function () {
						fn.each(function () {

							if (this.status() == query) {
								seatSet.push(this.settings.id, this);
							}
						});

						return seatSet;
					})();
				})();

			},
			set: function set() {//inherits some methods
				var fn = this;

				return {
					seats: [],
					seatIds: [],
					length: 0,
					status: function () {
						var args = arguments,
							that = this;
						//if there's just one seat in the set and user didn't pass any params, return current status
						return this.length == 1 && args.length == 0 ? this.seats[0].status() : (function () {
							//otherwise call status function for each of the seats in the set
							$.each(that.seats, function () {
								this.status.apply(this, args);
							});
						})();
					},
					node: function () {
						return fn.node.call(this);
					},
					each: function () {
						return fn.each.call(this, arguments[0]);
					},
					get: function () {
						return fn.get.call(this, arguments[0]);
					},
					find: function () {
						return fn.find.call(this, arguments[0]);
					},
					set: function () {
						return set.call(fn);
					},
					push: function (id, seat) {
						this.seats.push(seat);
						this.seatIds.push(id);
						++this.length;
					}
				};
			},
			//get one object or a set of objects
			get: function (seatsIds) {
				var fn = this;

				return typeof seatsIds == 'string' ?
					fn.seats[seatsIds] : (function () {

						var seatSet = fn.set();

						$.each(seatsIds, function (index, seatId) {
							if (typeof fn.seats[seatId] === 'object') {
								seatSet.push(seatId, fn.seats[seatId]);
							}
						});

						return seatSet;
					})();
			}
		});


		if (temp_cloumn > 0) {
			if (model == TIAOXINGTABLE) {
				$('#screen').css({ 'width': 80 * temp_cloumn - 20 + 'px', });
				$(fn).css({ 'width': 80 * temp_cloumn - 20 + 'px', 'height': 80 * temp_row + 'px' });
				if($(fn).find('.seatCharts-row').length == 2) {
					$(fn).find('.seatCharts-row').eq(-1).css({'margin-top': '40px'});
				}
			} else if (model == CIRCLETABLE) {
				$('#screen').css({ 'width': 60 * temp_cloumn + 'px', });
				$(fn).css({ 'width': 60 * temp_cloumn + 'px', 'height': 60 * temp_row + 'px' });
			} else {
				$('#screen').css({ 'width': 70 * temp_cloumn + 'px', });
				$(fn).css({ 'width': 70 * temp_cloumn + 'px' });
			}
		}


		$('#seat-map').on('mousemove', function (e) {
			if (opcityBlock_move) {
				var L = $('#seat-map').offset().left;
				var T = $('#seat-map').offset().top;
				var scrollLeft = $('#seat-map').scrollLeft();
				var scrollTop = $('#seat-map').scrollTop();
				floatingLayer.css({ left: e.clientX - L + scrollLeft + 1, top: e.clientY - T + scrollTop + 1 });
			}
		}).on('mouseup', function (e) {
			if (opcityBlock_move) {
				store_setState({
					floatingLayer_end_dom: $(e.target).closest('.seatCharts-container'),
					floatingLayer_end_seatId: $(e.target).attr('id'),
					floatingLayer_end_hrmId: $(e.target).attr('hrmid'),
					end_table_number: tableNum,
					end_seat_label: $(e.target).attr('label')
				});
				if ($(e.target).attr('hrmid') && $(e.target).attr('hrmid') != '') {
					getModal();
				} else {
					if ($(e.target).attr('hrmid') == undefined) {
					} else {
						var beforeDom = store_getState('floatingLayer_before_dom');
						var beforeSeatId = store_getState('floatingLayer_before_seatId');
						var beforeHrmId = store_getState('floatingLayer_before_hrmId');

						var currentSeatid = $(e.target).attr('id');
						var currentSeatLabel = $(e.target).attr('label');
						var currentTablenum = $(e.target).attr('tablenum');

						var item = { id: beforeHrmId, name: $(beforeDom).find('#' + beforeSeatId).text(), seatId:  currentSeatid, seatLabel: currentSeatLabel, 
							tableNum: currentTablenum, memberType: '-999' };
						var parentDom = $(e.target).closest('.seatCharts-container');
						$(e.target).text($(beforeDom).find('#' + beforeSeatId).text()).attr('hrmid', beforeHrmId);
						$(beforeDom).find('#' + beforeSeatId).attr('hrmid', '').text($(beforeDom).find('#' + beforeSeatId).attr('label'));
						$(beforeDom).find('.opcityBlock, .close').remove();
						$.change_map($(beforeDom), { id: '', name: '', memberType: '', }, beforeSeatId, 'arrange', changeHrm);
						$.change_map(parentDom, item, currentSeatid, 'arrange', changeHrm);
					}
				}
				$('.floatingLayer').remove();

				opcityBlock_move = false;
			}
		})
		return fn.data('seatCharts');
	}

	// 拖拽 start
	$.fn.dragging = function (params) {
		const right_Menu = params.right_Menu;
		const Padding = 0;
		const model = params.model;
		var _this = this;
		var selectSeats = SEATS;
		var $seatmap = $(_this);
		var isDrage = false;
		var start_isValid = false, end_isValid = false;
		var startX, startY, mouseX, mouseY, startrow, startcol, endrow, endcol, timestart, timeend;
		$seatmap.on('mousedown', function (e) {
			if (model == TIAOXINGTABLE) { // 处理点击出现边角
				$seatmap.children('div[class=seatCharts-row]:last-child').children(':first').css({ 'border-radius': '30px' });
				$seatmap.children('div[class=seatCharts-row]:last-child').children(':last').css({ 'border-radius': '30px' });
			}
			$('#mouseline').remove();
			$('#right-menu').remove();
			$('#mask').remove();
			var $id = $(e.target).attr('id');

			timestart = new Date().getTime();
			var $mouseline = document.createElement("div");
			var L = $seatmap.offset().left, T = $seatmap.offset().top;

			$mouseline.style.cssText = "position:absolute;width:10px;height:10px;font-size:0px;margin:0px;padding:0px;border:1px dashed #0099FF;" +
				"background-color:#C3D5ED;z-index:1000;filter:alpha(opacity:60);opacity:0.6;display:none;";
			$mouseline.id = "mouseline";

			// if($(e.target).hasClass('available')) {
			// 	start_isValid = true;
			// 	$seatmap.append($mouseline);
			// }else{
			// 	start_isValid = false;
			// }

			var getcol = function (e) { // 列
				var col = -999;
				if (e.target.className == 'seatCharts-row') {
					col = Math.ceil((e.offsetX) / 56); // padding:20
				} else {
					if (e.target.getAttribute('col') == null) {
						col = e.target.getAttribute('id').split("_")[1];
					} else {
						col = e.target.getAttribute('col');
					}
				}
				return parseInt(col, 10);
			}

			const getrow_col = (id, e) => {
				var row, col;
				if (id) {
					row = id.split("_")[0];
					col = id.split("_")[1];
				} else {
					col = Math.ceil(e.offsetX / 56);
					row = e.target.getAttribute('row');
				}
				return [parseInt(row, 10), parseInt(col, 10)];
			}

			var getrow = function (e) { // 行
				var row = -999;
				if (e.target.className == 'seatCharts-row') {
					row = Math.ceil((startY - T - Padding) / 35);
				} else {
					if (e.target.getAttribute('row') == null) {
						row = e.target.getAttribute('id').split("_")[0];
					} else {
						row = e.target.getAttribute('row');
					}
				}
				return parseInt(row, 10);
			}
			startX = e.clientX;
			startY = e.clientY;

			$mouseline.style.left = startX + "px";// 获取坐标
			$mouseline.style.top = startY + "px";

			if ($(e.target).hasClass('available')) {
				start_isValid = true;
				var settimeout = setTimeout(() => {
					$seatmap.append($mouseline);
					startcol = getrow_col($id, e)[0];
					startrow = getrow_col($id, e)[1];
				}, 250);
			} else {
				start_isValid = false;
			}


			isDrage = true;

			$seatmap.on('mousemove', function (e) {
				mouseX = e.clientX;
				mouseY = e.clientY;
				if ($mouseline.style.display == "none") {
					$mouseline.style.display = '';
				}
				if (isDrage) {
					if ((mouseX - startX) < 0 && (mouseY - startY) < 0) {
						$mouseline.style.left = Math.min(mouseX, startX) - L + 5 + "px";
						$mouseline.style.top = Math.min(mouseY, startY) - T + 5 + "px";
					} else {
						$mouseline.style.left = Math.min(mouseX, startX) - L + "px";
						$mouseline.style.top = Math.min(mouseY, startY) - T + "px";
					}
					$mouseline.style.width = Math.abs(mouseX - startX) - 5 + "px";
					$mouseline.style.height = Math.abs(mouseY - startY) - 5 + "px";
				}
			});

			$seatmap.on('mouseup', function (e) {
				timeend = new Date().getTime();
				if ((timeend - timestart > 250)) { // 时间间隔大于250ms为点击事件
					endcol = getrow_col($(e.target).attr('id'), e)[0];
					endrow = getrow_col($(e.target).attr('id'), e)[1];
					var getmax_min = function (a, b, type) {
						var t = a;
						if (type == 'max') {
							t = a > b ? a : b;
						} else {
							t = a > b ? b : a;
						}
						return t;
					}

					function setSelectedStyle(_this, item, startrow, startcol, endrow, endcol, _that) {
						var value = item.map;
						for (var y = getmax_min(startrow, endrow, 'min'); y <= getmax_min(startrow, endrow, 'max'); y++) {
							for (var x = getmax_min(startcol, endcol, 'min'); x <= getmax_min(startcol, endcol, 'max'); x++) {
								var id = '#' + x + '_' + y;
								var idstr = x + '_' + y;
								if (model == TIAOXINGTABLE && item.key == 'passageway') {
									$(_that).find(id).css({ 'background-color': '#E4E9F0', 'color': '#E4E9F0' });
								} else {
									$(_that).find(id).css('background-color', item.backgroundColor);
								}
								$.change_map(_that, item, idstr); // 设置map
							}
						}
					}

					function removeDom() {
						$('#mouseline').remove();
						$('#right-menu').remove();
						$('#mask').remove();
					}

					function getRightMenu(_this, startrow, startcol, endrow, endcol, _that) {
						$('#right-menu').remove();
						$('#mask').remove();
						var $mask = $('<div id="mask"></div>').on('click', function () {
							$(this).remove();
							removeDom();
						});
						var $rightmenu = $('<div id="right-menu"></div>')
							.addClass('right-menu')
						$rightmenu.css({
							'left': e.clientX - $('#seat-map').offset().left + 40 + 'px',
							'top': e.clientY - $('#seat-map').offset().top + 'px'
						})

						$.each(right_Menu, function (index, item) {
							var spanstr = $('<div></div>')
								.addClass('menu-list')
								.text(item.value)
								.on('click', function (e) {
									setSelectedStyle(_this, item, startrow, startcol, endrow, endcol, _that);
									$('#mouseline').remove();
									$('#right-menu').remove();
									$('#mask').remove();
								})
							$rightmenu.append(spanstr)
						})
						$('#seat-map').after($rightmenu);
						$('#seat-map').after($mask);
					}

					start_isValid && getRightMenu(e, startrow, startcol, endrow, endcol, _this)

				} else {
					$('#mouseline').remove();
					clearTimeout(settimeout);
				}
				isDrage = false;
			});
		})
	}
	// 拖拽 end


	// 获取map
	$.fn.getMap_pre = function getMap(model, map, row, col, circleCount) { // model: 会场类型 map: 排位信息 circleCount： 圆桌人数
		var map = [];
		var mapObj = [];
		var tempName;
		if (model == JUXINGTABLE) {//矩形桌
			for (var i = 0; i < row; i++) {
				tempName = "";
				for (var j = 0; j < col; j++) {
					tempName += "e";
				}
				map.push(tempName);
			}
		} else if (model == TIAOXINGTABLE) {//条形桌
			for (var i = 0; i < row; i++) {
				tempName = "";
				for (var j = 0; j < col; j++) {
					if (((i == 0 || i == row - 1) && (j == 0 || j == col - 1)) || i != 0 && i != row - 1 && j > 0 && j < col - 1) {
						tempName += "_";
					} else {
						tempName += "e";
					}
				}
				map.push(tempName);
			}
		} else if (model == CIRCLETABLE) {//圆桌
			var hrmCount = circleCount;
			var row = Math.ceil(hrmCount / 4) + 2;
			var col = Math.ceil((hrmCount - 2 * (row - 2)) / 2) + 2;
			var count = hrmCount;
			for (var y = 1; y <= row; y++) {
				var temp = '';
				for (var x = 1; x <= col; x++) {
					if ((y == 1 || y == row) && (1 < x && x < col) || (x == 1 || x == col) && (1 < y && y < row)) {
						if (count > 0) {
							temp = temp + 'e';
							count--;
						} else {
							temp = temp + 'w';
						}
					} else {
						temp = temp + '_';
					}
				}
				map.push(temp);
			}
		}

		map && map.map((res, x) => {
			let arr = [];
			res.split('') && res.split('').map((v, y) => {
				let seatItem = { map: v, showname: '', hrmid: '', bgcolor: '', seatId: x + '_' + y };
				arr.push(seatItem);
			})
			mapObj.push(arr);
		});

		return mapObj;
	}

})(jQuery);
